#
#    Pixel War (Cliente) - Cliente de Juego Multiplayer Online
#    Copyright (C) 2010 - Francisco Rivera
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import os
import math
from threading import Thread
import pygame


class Singleton(type):
 
    def __init__(cls, name, bases, dct):
        cls.__instance = None
        type.__init__(cls, name, bases, dct)
 
    def __call__(cls, *args, **kw):
        if cls.__instance is None:
            cls.__instance = type.__call__(cls, *args,**kw)
        return cls.__instance


class JThread(Thread):

    JUGANDO = True

    def __init__(self):
        Thread.__init__(self)
        
    def cortar(self):
        JThread.JUGANDO = False


class Archivo:

    ''' Lee un archivo y lo almacena como una cadena '''

    def __init__(self, nombre):    
        # Nos posicionamos en la carpeta correspondiente
        ruta = os.path.join("src", nombre)
        # Contenedor
        self.buffer = []
        # Abrimos el archivo
        archivo = open(ruta, 'Ur')
        # Leemos y almacenamos
        while True:
            linea = archivo.readline()
            if not linea:
                break
            if not linea.startswith("#"):
                self.buffer.append(linea.rstrip('\n'))
                
        print 'Archivo:', nombre, 'cargado con exito.'


class ArchivoEditable:

    def __init__(self, carpeta, nombre):
        # nos posicionamos en la carpeta correspondiente
        ruta = os.path.join(carpeta, nombre)
        # Abrimos el archivo
        self.archivo = open(ruta, 'w')
        
    def escribir(self, string):
        self.archivo.write(string)
        
    def cerrar(self):
        self.archivo.close()


class Fuente:

    def __init__(self, size):
        pygame.font.init()
        self.size = size
        self.nombre = "cubicfive10.ttf"
        self.cargar()
        
    def render(self, texto, color):
        ''' Devuelve un surface con el texto y color indicado '''        
        return self.fuente.render(texto, False, color)
        
    def cargar(self):    
        ruta = os.path.join("src", self.nombre)
        # creamos la fuente
        self.fuente = pygame.font.Font(ruta, self.size)
        
        white = (255,255,255,255)
        string1 = Text("Cow!", fontsize=256, color=white)
        
        
class SpriteLoader:
    ''' Clase para cargar y almacenar las imagenes '''
    
    ZOOM = 3
    DIM = 12
    SQM = DIM * ZOOM
    FORMATO = '.png'
        
    def __init__(self):    
        self.sprites = {}
        self.carpeta = "sprites"
        self.nombre_archivo = "sprites.pws"
        self.cargarSprites()
        
    def cargarSprites(self):            
        self.archivo = Archivo(self.carpeta, self.nombre_archivo)
        self.parseDatos()
            
    def parseDatos(self):            
        ''' Separa los id's, los sprites, el parametro de transparencia y el de bloqueo. Despues los carga '''        
        for i in self.archivo.buffer:
            error = False
            id, nombre, trans, bloq, capa, mult = i.split('-')
            # ID = 2 caracteres
            if not len(id) == 2:
                error = True
                print 'Error: ID distinto de 2 caracteres'
            # Nombre de archivo en minusculas
            if not nombre.islower():
                error = True
                print 'Error: Nombre de archivo no es completamente en mayuscula'
            # Transparencia = 't' o 'n'
            if not trans in ('t', 'n'):
                error = True
                print 'Error: Parametro de transparencia no valido'
            if not bloq in ('b', 'n'):
                error = True
                print 'Error: Parametro de bloqueo no valido'
            if not capa in ('s', 'o'):
                error = True
                print 'Error: Parametro de capa no valido'
                
            if error:
                print 'Revise el sprite:', i, ' - NO SE CARGARA'
            else:
                self.cargar(id, nombre, trans, bloq, capa, mult)
        ## sprite vacio
        self.sprites['00'] = None, None

    def cargar(self, id, nombre, trans, bloq, capa, mult):
        # Completamos el nombre de archivo
        nombre += self.FORMATO
        
        # Cargamos y ampliamos la imagen
        ruta = os.path.join(self.carpeta, nombre)
        if os.path.isfile(ruta):
            img = pygame.image.load(ruta)
            # ampliamos?
            if mult == 'm':
                img = self.ampliar(img)
        else:
            print "Nombre de archivo incorrecto", nombre
            return
            
        # Convertimos la imagen para incrementar la velocidad en el dibujado
        img = img.convert()#_alpha()
        if trans == 't':
            img.set_colorkey((255, 0, 255), pygame.RLEACCEL)#, pygame.RLEACCEL)
        #else:
        #    img = img.convert()
        bloqueante = bloq == 'b'
        objeto = capa == 'o'
            
        # La agregamos al diccionario
        self.sprites[id] = (img, bloqueante, objeto)
        
    def ampliar(self, imagen):        
        ''' ampliar(imagen) --> imagen ampliada * 3 '''        
        return pygame.transform.scale(imagen, (imagen.get_width() * self.ZOOM, imagen.get_height() * self.ZOOM))
        
    def getSprite(self, id):
        return self.sprites[id][0]
        
    def esBloqueante(self, id):
        return self.sprites[id][1]
        
    def esObjeto(self, id):
        return self.sprites[id][2]